package team.nmsg.ge.system.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import team.nmsg.ge.system.bean.SysRole;

/**
 * sql 查询语句 字符串拼接 工具类
 * @author Guodeqi
 *
 */
public class SysQueryCriteriaHelper {

	
	
	
	public static String createInCriteriaStrByRoleId( Collection<SysRole> roles ){
		
		if( roles== null || roles.size()==0 ){
			return " ( ) ";
		}
		int size = roles.size();
		int counter = 0 ;
		StringBuilder inCriteria = new StringBuilder( " ( " );
		Iterator<SysRole> iterator = roles.iterator();
		while(  iterator.hasNext() ){
			SysRole next = iterator.next();
			Integer moid = next.getRoleId();
			if( counter ==  size-1){
				inCriteria.append( moid +" ");
			}else{
				inCriteria.append( moid +", ");
			}
			counter++;
		}
		inCriteria.append(" ) ");
		
		return inCriteria.toString();
	}
	
	public static String createInCriteriaStrByIntList( Collection<Integer> flags ){
		
		if( flags== null || flags.size()==0 ){
			return " ( ) ";
		}
		int size = flags.size();
		int counter = 0 ;
		StringBuilder inCriteria = new StringBuilder( " ( " );
		Iterator<Integer> iterator = flags.iterator();
		while(  iterator.hasNext() ){
			Integer next = iterator.next();
			if( counter ==  size-1){
				inCriteria.append( next +" ");
			}else{
				inCriteria.append( next +", ");
			}
			counter++;
		}
		inCriteria.append(" ) ");
		
		return inCriteria.toString();
		
	}
	
	public static String createInCriteriaStrByLongList( Collection<Long> flags ){
		
		if( flags== null || flags.size()==0 ){
			return " ( ) ";
		}
		int size = flags.size();
		int counter = 0 ;
		StringBuilder inCriteria = new StringBuilder( " ( " );
		Iterator<Long> iterator = flags.iterator();
		while(  iterator.hasNext() ){
			Long next = iterator.next();
			if( counter ==  size-1){
				inCriteria.append( next +" ");
			}else{
				inCriteria.append( next +", ");
			}
			counter++;
		}
		inCriteria.append(" ) ");
		
		return inCriteria.toString();
		
	}
	
	
	public static String createInCriteriaStrByStrList( Collection<String> flags ){
		
		if( flags== null || flags.size()==0 ){
			return " ( ) ";
		}
		int size = flags.size();
		int counter = 0 ;
		StringBuilder inCriteria = new StringBuilder( " ( " );
		Iterator<String> iterator = flags.iterator();
		while(  iterator.hasNext() ){
			String next = iterator.next();
			if( counter ==  size-1){
				inCriteria.append( " '" +next +"' ");
			}else{
				inCriteria.append(  " '" +next +"', ");
			}
			counter++;
		}
		inCriteria.append(" ) ");
		
		return inCriteria.toString();
	}
	
	
	private static final String UPD_AND = " , ";
	
	public static final String KEY_SQL_WITHOUT_WHERE = "sqlWithOutWhere";
	public static final String KEY_SQL_ARGS = "updSqlArgs";
	/**
	 * 	 * 创建update sql 语句
	 * @param dbObj  原始实体
	 * @param newObj	新实体
	 * @param dstTable	更新目标表格对应的实体类的class
	 * @param filterFields	不需要比较的属性名称， 如没有则可以为null
	 * @return	sql:sql语句 不带where 条件  args 参数列表	null:不需要更新
	 * @throws IntrospectionException	
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static Map<String,Object> createUpdateSql(  Object dbObj , Object newObj , Class dstTable ,Set<String> filterFields ) 
			throws  IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
		
		Map<String,Object> sqlAndArgs = new HashMap<String, Object>();
		List args = new ArrayList();
		String tableName = dstTable.getSimpleName() ;
		StringBuilder updateSql = new StringBuilder( " update "+tableName+" set " );
		boolean firstCell = true;
		Field[] fields = dstTable.getDeclaredFields();
		for( int i=0; i<fields.length ;i++ ){
			Field field = fields[i];
			String tmpFieldName = field.getName();

			int modifiers = field.getModifiers();//静态 或 final 不遍历
			if( Modifier.isStatic(modifiers)  || Modifier.isFinal(modifiers) ){
				continue;
			}
			if( filterFields != null && (filterFields.contains(tmpFieldName) || filterFields.contains(tmpFieldName.toLowerCase()))  ){
				continue;
			}
			PropertyDescriptor pd = new PropertyDescriptor(tmpFieldName, dstTable);
			Method readMethod = pd.getReadMethod();
			Class returnType = readMethod.getReturnType();
			if( isBasicType(returnType) || isBasicWrapperType(returnType) ){
				Object bdValue = readMethod.invoke(dbObj);
				Object newValue = readMethod.invoke(newObj);
				boolean toUpd = false;
				if( bdValue!=null && !bdValue.equals(newValue) ){
					toUpd = true;
				}else if(bdValue==null && newValue!=null){
					toUpd = true;
				}
				if( toUpd ){
					if( !firstCell ){
						updateSql.append( UPD_AND );
					}else{
						firstCell = false;
					}
					
					updateSql.append(" "+tmpFieldName+"=? ");
					args.add(newValue);
					
				}
			}
		}
		if( args.size()==0 ){
			return null;
		}
		sqlAndArgs.put( KEY_SQL_WITHOUT_WHERE , updateSql.toString());
		sqlAndArgs.put(KEY_SQL_ARGS, args );
		return sqlAndArgs;
	}
	
	public static boolean isBasicType(Class clazz){
		String simpleName = clazz.getSimpleName();
		if(	"int".equals(simpleName)
				||"byte".equals(simpleName)  
				||"short".equals(simpleName) 
				||"long".equals(simpleName)  
				||"char".equals(simpleName)  
				||"float".equals(simpleName) 
				||"double".equals(simpleName)   
				||"boolean".equals(simpleName)   
		){
			return true;
		}
		return false;
	}
	
	public static boolean isBasicWrapperType(Class clazz){
		String simpleName = clazz.getSimpleName();
		if(	 Integer.class.getSimpleName().equals(simpleName) 
				|| Byte.class.getSimpleName().equals(simpleName)
				|| Short.class.getSimpleName().equals(simpleName)
				|| Long.class.getSimpleName().equals(simpleName)
				|| Character.class.getSimpleName().equals(simpleName)
				|| Float.class.getSimpleName().equals(simpleName)
				|| Double.class.getSimpleName().equals(simpleName)
				|| Boolean.class.getSimpleName().equals(simpleName)
				|| String.class.getSimpleName().equals(simpleName) ){
			return true;
		}
		return false;
	}
	
	
	public static void main(String[] args) {}
	
}
